import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_application_1/utils/utils.dart';

class TabbarPage extends StatefulWidget {
  @override
  _TabbarPageState createState() => _TabbarPageState();
}

class _TabbarPageState extends State<TabbarPage> with TickerProviderStateMixin {
  List<String> _tabList = [
    'one',
    'two',
    'three',
    'four',
    'five',
    'six',
    'seven',
    'eight',
    'nine'
  ];

  late TabController _tabController;

  late PageController _pageController;

  ValueNotifier<int> _currentIndex = ValueNotifier<int>(0);

  // 滑动时 tab 有动画，但是回调事件慢
  void _tabChange() {
    _currentIndex.value = _tabController.index;
  }

  // 滑动时 tab 没有动画，但是回调事件快
  // 用了判断是否点击跳转中，避免点击 tab 跳转时触发 PageView 的 onPageChanged
  bool _onTabing = false;

  void _onPageChanged(int page) {
    if (!_onTabing) {
      _tabController.animateTo(page);
    }
  }

  void _onTabTap(int page) {
    if (_onTabing) return;
    _onTabing = true;
    _pageController
        .animateToPage(
      page,
      duration: kTabScrollDuration,
      curve: Curves.ease,
    )
        .then((_) {
      _currentIndex.value = page;
      _onTabing = false;
    });
  }

  @override
  void initState() {
    super.initState();

    _tabController = TabController(
      initialIndex: _currentIndex.value,
      length: _tabList.length,
      vsync: this,
    );

    _pageController = PageController(
      initialPage: _currentIndex.value,
    );

    _tabController.addListener(_tabChange);
  }

  @override
  void dispose() {
    super.dispose();

    Utils.updateStatusBarStyle(SystemUiOverlayStyle(
      statusBarIconBrightness: Brightness.dark,
      statusBarColor: Colors.transparent,
    ));

    _tabController.dispose();
    _pageController.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return AnnotatedRegion<SystemUiOverlayStyle>(
      value: SystemUiOverlayStyle(
        statusBarIconBrightness: Brightness.light,
        statusBarColor: Theme.of(context).primaryColor,
      ),
      child: SafeArea(
        top: true,
        child: Scaffold(
          body: CustomScrollView(
            slivers: [
              // 普通用法
              SliverToBoxAdapter(
                child: Container(
                  color: Theme.of(context).primaryColor,
                  child: TabBar(
                    controller: _tabController,
                    isScrollable: true,
                    indicatorColor: Colors.white,
                    indicatorPadding:
                        EdgeInsets.symmetric(vertical: 3, horizontal: 10),
                    onTap: _onTabTap,
                    tabs: _tabList
                        .map(
                          (name) => Tab(
                            text: name,
                          ),
                        )
                        .toList(),
                  ),
                ),
              ),
              // 自定义 indicator
              SliverToBoxAdapter(
                child: Container(
                  child: TabBar(
                    controller: _tabController,
                    isScrollable: true,
                    indicator: BoxDecoration(
                      color: Theme.of(context).primaryColor,
                      border: Border(
                        top: BorderSide(
                          width: 46,
                          color: Theme.of(context).primaryColor,
                        ),
                      ),
                    ),
                    unselectedLabelColor: Colors.black,
                    onTap: _onTabTap,
                    tabs: _tabList
                        .map(
                          (name) => Tab(
                            text: name,
                          ),
                        )
                        .toList(),
                  ),
                ),
              ),
              // 自定义 label
              SliverToBoxAdapter(
                child: Container(
                  color: Theme.of(context).primaryColor,
                  child: TabBar(
                    controller: _tabController,
                    isScrollable: true,
                    indicator: BoxDecoration(
                      color: Colors.transparent,
                    ),
                    indicatorWeight: 0,
                    indicatorColor: Colors.transparent,
                    onTap: _onTabTap,
                    tabs: List.generate(
                      _tabList.length,
                      (index) => ValueListenableBuilder(
                        valueListenable: _currentIndex,
                        builder: (BuildContext context, int currentIndex,
                            Widget? child) {
                          return Container(
                            height: 46,
                            alignment: Alignment.center,
                            child: Container(
                              width: 60,
                              height: 26,
                              decoration: BoxDecoration(
                                color: currentIndex == index
                                    ? Colors.amberAccent
                                    : Colors.white,
                                borderRadius: BorderRadius.circular(20),
                              ),
                              alignment: Alignment.center,
                              child: Text(
                                _tabList[index],
                                style: TextStyle(
                                  fontSize: 13,
                                  color: currentIndex == index
                                      ? Colors.white
                                      : Colors.black,
                                ),
                              ),
                            ),
                          );
                        },
                      ),
                    ),
                  ),
                ),
              ),

              SliverFillRemaining(
                // 滑动时 tab 有动画，但是回调事件慢
                // child: TabBarView(
                //   controller: _tabController,
                //   children: _tabList
                //       .map(
                //         (name) => Container(
                //           child: Center(
                //             child: Text(name),
                //           ),
                //         ),
                //       )
                //       .toList(),
                // ),
                // 滑动时 tab 没有动画，但是回调事件快
                child: PageView(
                  controller: _pageController,
                  children: _tabList
                      .map(
                        (name) => Container(
                          child: Center(
                            child: Text(name),
                          ),
                        ),
                      )
                      .toList(),
                  onPageChanged: _onPageChanged,
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }
}
